package recite.word.service.base.common.interceptor;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.symmetric.SM4;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import recite.word.redis.constant.RedisConstant;
import recite.word.redis.util.RedisUtil;
import recite.word.service.base.common.enums.ResponseEnum;
import recite.word.service.base.common.response.ResponseResult;
import recite.word.service.base.common.threadLocal.UserContent;
import recite.word.service.base.util.sm.SmartConstant;
import recite.word.service.base.util.sm.SmartUtil;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 用户鉴权拦截
 */
@Slf4j
@Component
public class UserInterceptor implements HandlerInterceptor {

    @Autowired
    private RedisUtil redisUtil;

    /***
     * 在请求处理之前进行调用(Controller方法调用之前)
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler){
//        if (true) {
//            return true;
//        }
        if (request.getMethod().equals("OPTIONS")){
            return true;
        }

        String token = request.getHeader("Authorization");
        log.error("获取的token为：{}", token);
        if(StrUtil.isBlank(token)){
            log.error("token为空！！！");
            tokenDenied(response, "请先登录");
            return false;
        }

        final SM4 sm4 = SmartUtil.getSM4(SmartConstant.SM4_DEFAULT_KEY);
        String jsonStr = "";
        try {
            jsonStr = SmartUtil.sm4Decrypt(sm4, token);
        } catch (Exception e) {
            log.error("解密失败：" + e);
            tokenDenied(response, "请先登录");
            return false;
        }
        //解密后
        if("".equals(jsonStr)){
            log.error("token解密为空!");
            tokenDenied(response, "请先登录");
            return false;
        }

        JSONObject jsonObject = JSONUtil.parseObj(jsonStr);
        if (null != jsonObject.get("userId")){
            String userId = jsonObject.get("userId").toString();
            Object o = redisUtil.get(RedisConstant.LOGIN_PREFIX + userId);
            //登录成功双层判断
            if (null == o) {
                log.error("redis获取不到用户对应的token,当前token:{},redis里的token:{}", token, o);
                tokenDenied(response, "登录已失效，请重新登录");
                return false;
            }
            if (!token.equals(o.toString())) {
                log.error("redis对用用户token不匹配，当前token:{},redis里的token:{}", token, o);
                tokenDenied(response, "账号已在其它地方登录");
                return false;
            }
            //重置key过期
            redisUtil.expire(RedisConstant.LOGIN_PREFIX + userId, RedisConstant.REDIS_DEFAULT_USER_TIMEOUT);
            redisUtil.expire(RedisConstant.PERMISSION_PREFIX + userId, RedisConstant.REDIS_DEFAULT_USER_TIMEOUT);
            UserContent.set(Long.valueOf(userId));
            return true;
        }else {
            log.error("数据解密没有userId！");
            tokenDenied(response, "请先登录");
            return false;
        }
    }

    private void tokenDenied(HttpServletResponse response, String error){
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        response.setStatus(HttpServletResponse.SC_OK);
        ObjectMapper mapper = new ObjectMapper();
        try {
            mapper.writeValue(response.getWriter(), ResponseResult.failed(ResponseEnum.LOGIN_FAILURE,error));
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
}
